/*
 *  Copyright 2010 dmakariev.
 *
 */
package org.deltaset.faces.upload;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;

/**
 *
 * @author dmakariev
 */
class RequestParser {

    private RequestParser() {
    }

    static RequestParser parse(final HttpServletRequest request) throws IOException {
        final RequestParser parser = new RequestParser();
        return parser.parseRequest(request);
    }
    private static final Logger logger = Logger.getLogger(RequestParser.class.getName());
    private final Map<String, List<String>> formParameterMap = new LinkedHashMap<String, List<String>>();
    private final Map<String, List<DsFileItem>> fileParameterMap = new LinkedHashMap<String, List<DsFileItem>>();

    RequestParser parseRequest(final HttpServletRequest request) throws IOException {
        final ServletFileUpload servletFileUpload = new ServletFileUpload();
        try {
            for (FileItemIterator it = servletFileUpload.getItemIterator(request); it.hasNext();) {
                final FileItemStream fileItemStream = it.next();
                if (fileItemStream.isFormField()) {
                    addFormParameter(fileItemStream);
                } else {
                    addFileParameter(fileItemStream);
                }
            }
        } catch (FileUploadException e) {
            throw new IOException(e.getMessage());
        }
        return this;
    }

    void addFileParameter(final FileItemStream item) {
        logger.log(Level.INFO, "RequestParser adding fileParameter item.getName()={0}", item.getName());
        if (fileParameterMap.containsKey(item.getFieldName())) {
            fileParameterMap.get(item.getFieldName()).add(CurrentFileImpl.fromFileItemStream(item));
        } else {
            final List<DsFileItem> items = new ArrayList<DsFileItem>();
            items.add(CurrentFileImpl.fromFileItemStream(item));
            fileParameterMap.put(item.getFieldName(), items);
        }
    }

    void addFormParameter(final FileItemStream item) throws IOException {
        if (formParameterMap.containsKey(item.getFieldName())) {
            formParameterMap.get(item.getFieldName()).add(Streams.asString(item.openStream()));
        } else {
            final List<String> items = new ArrayList<String>();
            items.add(Streams.asString(item.openStream()));
            formParameterMap.put(item.getFieldName(), items);
        }
    }

    /**
     * @return the formParameterMap
     */
    Map<String, List<String>> getFormParameterMap() {
        return Collections.unmodifiableMap(formParameterMap);
    }

    /**
     * @return the fileParameterMap
     */
    Map<String, List<DsFileItem>> getFileParameterMap() {
        return Collections.unmodifiableMap(fileParameterMap);
    }
}
